﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DirectoryInfoExtentions.cs" company="Elilink">
//   Defor
// </copyright>
// <summary>
//   The directory info extentions.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace STDULibrary.Tools
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Security.AccessControl;

    /// <summary>
    ///     The directory info extention.
    /// </summary>
    internal static class DirectoryInfoExtentions
    {
        #region Public Methods and Operators

        /// <summary>
        /// The get files by extensions.
        /// </summary>
        /// <param name="directory">The directory.</param>
        /// <param name="extensions">The extensions.</param>
        /// <returns>The collection.</returns>
        /// <exception cref="System.ArgumentNullException">If extensions are empty</exception>
        public static IEnumerable<FileInfo> GetFilesByExtensions(this DirectoryInfo directory, params string[] extensions)
        {
            if (extensions == null)
            {
                throw new ArgumentNullException("extensions");
            }

            try
            {
                IEnumerable<FileInfo> files = directory.EnumerateFiles();
                return files.Where(f => extensions.Contains(f.Extension));
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error getting files: {0}", ex.Message);
                return new List<FileInfo>();
            }
        }

        /// <summary>
        /// Determines whether this instance can read the specified directory.
        /// </summary>
        /// <param name="directory">The directory.</param>
        /// <returns><c>true</c> if this instance can read the specified directory; otherwise, <c>false</c>.</returns>
        public static bool CanRead(this DirectoryInfo directory)
        {
            var readAllow = false;
            var readDeny = false;
            var accessControlList = directory.GetAccessControl();
            var accessRules = accessControlList.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
            foreach (FileSystemAccessRule rule in accessRules)
            {
                if ((FileSystemRights.Read & rule.FileSystemRights) != FileSystemRights.Read)
                {
                    continue;
                }

                if (rule.AccessControlType == AccessControlType.Allow)
                {
                    readAllow = true;
                }
                else if (rule.AccessControlType == AccessControlType.Deny)
                {
                    readDeny = true;
                }
            }

            return readAllow && !readDeny;
        }

        #endregion
    }
}